#include "precompiled.hpp"
#include "jam_ast.hpp"

eval_node::eval_node(parse_node_ptr left_tree,parse_node_ptr right_tree,
	condition_type operation) : operation_(operation)
{
	//Prune unneccessary EXPR_EXISTS nodes
 
	if (left_tree->get_node_id()==eval_node::node_id)
	{
		const eval_node *left=static_cast<const eval_node*>(left_tree.get());
		if (left->operation_==EXPR_EXISTS)
			left_tree_=left->left_tree_;
		else
			left_tree_=left_tree;
	} else
		left_tree_=left_tree;

	if (right_tree->get_node_id()==eval_node::node_id)
	{
		const eval_node *right=static_cast<const eval_node*>(right_tree.get());
		if (right->operation_==EXPR_EXISTS)
			right_tree_=right->left_tree_;
		else
			right_tree_=right_tree;
	} else
		right_tree_=right_tree;
}

///////////////////////////////////////////////////////////////////////////////////////
////// AST visitation implementation
///////////////////////////////////////////////////////////////////////////////////////
void append_node::visit(parse_node_visitor *vis)
{
	vis->visit_append_node(this,left_tree_,right_tree_);
}

void eval_node::visit(parse_node_visitor *vis)
{
	vis->visit_eval_node(this,left_tree_,right_tree_,operation_);
}

void foreach_node::visit(parse_node_visitor *vis)
{
	vis->visit_foreach_node(this,var_values_tree_,rule_tree_,
		index_var_name_,is_var_local_);
}

void if_node::visit(parse_node_visitor *vis)
{
	vis->visit_if_node(this,condition_tree_,then_tree_,else_tree_);
}

void include_node::visit(parse_node_visitor *vis)
{
	vis->visit_include_node(this,file_name_tree_);
}

void list_node::visit(parse_node_visitor *vis)
{
	vis->visit_list_node(this,expand_string_);
}

void local_node::visit(parse_node_visitor *vis)
{
	vis->visit_local_node(this,var_list_tree_,val_list_tree_,rule_list_tree_);
}

void module_node::visit(parse_node_visitor *vis)
{
	vis->visit_module_node(this,module_name_tree_,module_content_tree_);
}

void class_node::visit(parse_node_visitor *vis)
{
	vis->visit_class_node(this,class_name_tree_,right_);
}

void null_node::visit(parse_node_visitor *vis)
{
	vis->visit_null_node(this);
}

void on_node::visit(parse_node_visitor *vis)
{
	vis->visit_on_node(this,list_tree_,rule_tree_);
}

void rule_node::visit(parse_node_visitor *vis)
{
	vis->visit_rule_node(this,params_tree_,name_);
}

void rules_node::visit(parse_node_visitor *vis)
{
	vis->visit_rules_node(this,rule_tree_,chained_rules_tree_);
}

void set_node::visit(parse_node_visitor *vis)
{
	vis->visit_set_node(this,var_names_tree_,val_tree_,operation_);
}

void settings_node::visit(parse_node_visitor *vis)
{
	vis->visit_settings_node(this,names_tree_,target_names_tree_,
		val_tree_,operation_);
}

void setcomp_node::visit(parse_node_visitor *vis)
{
	vis->visit_setcomp_node(this,rule_content_tree_,param_list_tree_,
		rule_name_,is_local_);
}

void setexec_node::visit(parse_node_visitor *vis)
{
	vis->visit_setexec_node(this,bind_var_tree_,action_name_,
		os_string_,flags_);
}

void switch_node::visit(parse_node_visitor *vis)
{
	vis->visit_switch_node(this,value_tree_,case_tree_);
}

void chain_node::visit(parse_node_visitor *vis)
{
	vis->visit_chain_node(this,left_tree_,right_tree_);
}

void case_node::visit(parse_node_visitor *vis)
{
	vis->visit_case_node(this,body_tree_,value_);
}

void while_node::visit(parse_node_visitor *vis)
{
	vis->visit_while_node(this,condition_tree_,body_tree_);
}

void lol_node::visit(parse_node_visitor *vis)
{
	vis->visit_lol_node(this,list_elem_,chained_list_);
}

void return_node::visit(parse_node_visitor *vis)
{
	vis->visit_return_node(this,list_res_);
}

void left_brace_node::visit(parse_node_visitor *vis)
{
	vis->visit_left_brace_node(this,body_tree_,rbracket_tree_);
}

void right_brace_node::visit(parse_node_visitor *vis)
{
	vis->visit_right_brace_node(this);
}
